/*
 * Copyright (c) 2016 VUI(https://git.oschina.net/durcframework/vui) All rights reserved.
 */


;(function(){
	
/**
 * 表格控件<br>
 * <pre>
grid = new VUI.Grid({
		renderId:'grid'
		,autoRender:true
		,url : listUrl
		,striped:true // 斑马线
		,idField:'orderId'
		,pagination :true
		,singleSelect :false // 是否单选
		,checkOnSelect :true
		,rownumbers :true
		,selectCache :true
		,queryParams:{name:'11',age:22}
		,onLoadError:function() {
			console.log('加载失败,尝试加载本地数据')
			loadData(); // 加载失败尝试加载本地数据
		}
		,onLoadSuccess:function(e) {
			console.log(e.data)
		}
		,onBeforeLoad:function(e) {
			console.log(e.data)
		}
		,onClickRow:function(e) {
			console.log('onClickRow,' + e.index + ' mobile:' + e.row.mobile)
		}
		,onDblClickRow :function(e) {
			console.log('onDblClickRow,' + e.index + ' mobile:' + e.row.mobile)
		}
		,onClickCell :function(e) {
			console.log('onClickCell,' + e.index + ' value:' + e.value + ' field:' + e.head.field)
		}
		,onDblClickCell :function(e) {
			console.log('onDblClickCell,' + e.index + ' value:' + e.value + ' field:' + e.head.field)
		}
		,onSortColumn :function(sortName,sortOrder) {
			console.log('onSortColumn sortName:' + sortName + ',sortOrder:'+sortOrder)
		}
		,onSelect :function(e) {
			console.log('onSelect index:' + e.index + ' mobile:' + e.row.mobile)
		}
		,onUnSelect :function(e) {
			console.log('onUnSelect index:' + e.index + ' city:' + e.row.cityName)
		}
		,onSelectAll :function(e) {
			console.log('onSelectAll rows.length=' + e.rows.length)
		}
		,onUnSelectAll :function(e) {
			console.log('onUnSelectAll rows.length=' + e.rows.length)
		}
		,onCheck :function(e) {
			console.log('onCheck index:' + e.index + ' mobile:' + e.row.mobile)
		}
		,onUncheck :function(e) {
			console.log('onUncheck index:' + e.index + ' mobile:' + e.row.mobile)
		}
		,onCheckAll :function(e) {
			console.log('onCheckAll rows.length=' + e.rows.length)
		}
		,onUnCheckAll :function(e) {
			console.log('onUncheckAll rows.length=' + e.rows.length)
		}
		,columns : [ [
			{
				checkbox : true
			},
			{
				field : 'cityName',
				title : '城市'
				,halign:'left'
				,styler: function(value,row,index){
					if (value == 12){
						return 'background-color:#ffee00;color:red;';
					}
				}

			},
			{
				field : 'mobile',
				title : '手机号'
				,align:'center'
				,formatter:function(val,obj,index,$td){
					if(val == 22) {
						$td.css({'background-color':'#ccc','color':'red'});
						return '<i>'+val+'</i>'
					}
					return val;
				}
			},
			{
				field : 'address',
				title : '地址'
			},
			{
				field : 'createDate',
				title : '创建时间'
				,sortable:true
			}] 
		]
	});
 * </pre>
 * @class VUI.Grid
 * @extends VUI.Component
 */
VUI.Class('Grid',{
	OPTS:$.extend({
		/**
		 * @cfg {String} url 请求URL
		 */
		url:null
		/**
		 * @cfg {String} method 请求方式
		 */
		,method:'GET'
		/**
		 * @cfg {String} idField 指明哪一个字段是标识字段。
		 */
		,idField:null
		/**
		 * @cfg {Object|Array} data 本地数据
		 */
		,data:null
		/**
		 * @cfg {String} width 表格宽度,'100%','auto'
		 */
		,width:'100%'
		/**
		 * @cfg {Array} pageList 在设置分页属性的时候 初始化页面大小选择列表。
		 */
		,pageList:[10,20,30,40,50]
		/**
		 * @cfg {Function} loadFilter 返回过滤数据显示。该函数带一个参数'data'用来指向源数据（即：获取的数据源，比如Json对象）。您可以改变源数据的标准数据格式。这个函数必须返回包含'total'和'rows'属性的标准数据对象。<br>
		 * <pre>
		 * 代码示例：

// 从Web Service（asp.net、java、php等）输出的JSON对象中移除'd'对象
new VUI.Grid({
	loadFilter: function(data){
		if (data.d){
			return data.d;
		} else {
			return data;
		}
	}
});
		 * </pre> 
		 */
		,loadFilter:null
		/**
		 * @cfg {Number} pageNumber 在设置分页属性的时候初始化页码。
		 */
		,pageNumber:1
		/**
		 * @cfg {Number} pageSize 在设置分页属性的时候初始化页面大小。
		 */
		,pageSize:10
		/**
		 * @cfg {Boolean} striped 是否显示斑马线效果。
		 */
		,striped:false
		/**
		 * @cfg {Boolean} pagination 如果为true，则在数据表格控件底部显示分页工具栏。
		 */
		,pagination:false
		/**
		 * @cfg {Boolean} rownumbers 如果为true，则显示一个行号列。
		 */
		,rownumbers:false
		/**
		 * @cfg {String} 
		 */
		,sortName:null
		/**
		 * @cfg {String} sortOrder 定义列的排序顺序，只能是'asc'或'desc'。
		 */
		,sortOrder:'ASC'
		/**
		 * @cfg {String} emptyDataMsg 没有数据时显示的提示
		 */
		,emptyDataMsg:'<div style="text-align:center;">无数据</div>'
		/**
		 * @cfg {Boolean} singleSelect 如果为true，则只允许选择一行。
		 */
		,singleSelect:false
		/**
		 * @cfg {Boolean} 
		 */
		,checkOnSelect:true
		/**
		 * @cfg {Object} queryParams 在请求远程数据的时候发送额外的参数。 <br>
		 <pre>
代码示例：

$('#dg').datagrid({
	queryParams: {
		name: 'easyui',
		subject: 'datagrid'
	}
});
</pre>
		 */
		,queryParams:{}
		/**
		 * @cfg {Boolean} selectCache 缓存勾选,true的话,表格翻页会记住之前的勾选状态
		 */
		,selectCache:false
		/**
		 * @cfg {Boolean} initLoad 初始化完成后立即加载数据
		 */
		,initLoad:true
		/**
		 * @cfg {Boolean} clickHighlight 点击行高亮
		 */
		,clickHighlight:true
		/**
		 * @cfg {Boolean} autoFit 自适应宽度,即单元格的宽度根据内容而定
		 */
		,autoFit:false
	}, VUI.Config.Grid)
	
	// ----- 事件注释 -----
		
	/** @event onLoadSuccess 在数据加载成功的时候触发。*/
	 
	/** 
	 * @event onLoadError 在载入远程数据产生错误的时候触发。 
	 * @param {Object} e e.xhr XMLHttpRequest对象,e.status 响应状态,e.error 错误信息
	 */
	
	/** 
	 * @event onBeforeLoad 在载入请求数据数据之前触发，如果返回false可终止载入数据操作。
	 * @param {Object} e e.data 查询参数
	 */
	 
	 /** 
	 * @event onClickRow 在用户点击一行的时候触发
	 * @param {Object} e e.index 行索引,e.row 行记录,e.target 点击的dom
	 */
	 
	 /** 
	 * @event onDblClickRow 在用户双击一行的时候触发
	 * @param {Object} e e.index 行索引,e.row 行记录,e.target 点击的dom
	 */
	 
	 /** 
	 * @event onClickCell 在用户点击一个单元格的时候触发。
	 * @param {Object} e e.value 单元格的值,e.head 表头配置对象,e.index 行索引,e.row 行记录,e.target 点击的dom
	 */
	 
	 /** 
	 * @event onDblClickCell 在用户双击一个单元格的时候触发
	 * @param {Object} e e.value 单元格的值,e.head 表头配置对象,e.index 行索引,e.row 行记录,e.target 点击的dom
	 */
	 
	 /** 
	 * @event onSortColumn 在用户点击排序时触发
	 * @param {String} sortName 排序字段名
	 * @param {String} sortOrder 排序方式,ASC DESC
	 */
	 
	 /** 
	 * @event onSelect 在用户选择一行时触发,单选情况下
	 * @param {Object} e e.index 行索引,e.row 行记录,e.$target input对象
	 */
	 
	 /** 
	 * @event onUnSelect 在用户取消选择一行时触发,单选情况下
	 * @param {Object} e e.index 行索引,e.row 行记录,e.$target input对象
	 */
	
	/** 
	 * @event onCheck 在用户勾选一行的时候触发
	 * @param {Object} e e.index 行索引,e.row 行记录,e.$target input对象
	 */
	 
	/** 
	 * @event onUncheck 在用户取消勾选一行的时候触发
	 * @param {Object} e e.index 行索引,e.row 行记录,e.$target input对象
	 */
	 
	/** 
	 * @event onCheckAll 在用户勾选所有行的时候触发
	 * @param {Object} e e.rows 选中的数据
	 */
	 
	/** 
	 * @event onUnCheckAll 在用户取消勾选所有行的时候触发
	 * @param {Object} e e.rows 选中的数据
	 */
		
	
	/**
	 * 构造函数
	 * @ignore
	 */
	,init:function(opts) {
		this._super(opts);
	}
	// @override
	,controller:function(data) {
		this.page = new VUI.Page(this);
		this.data = {}
		var columns = this.opt('columns')[0];
		
		$.extend(data,{
			page:this.page
			,grid:this
			,headers:columns
		});
	}
	// @override
	,afterBoot:function() {
		if(this.opt('initLoad')) {
			this.load();
		}
	}
	/**
	 * 清空勾选缓存
	 */
	,resetSelectCache:function() {
		this.selectCache = {};
	}
	/**
	 * @private
	 */
	,getSelectCache:function() {
		if(!this.selectCache) {
			this.selectCache = {};
		}
		return this.selectCache;
	}
	/**
	 * @private
	 */
	,isSelectCache:function() {
		return this.opt('selectCache');
	}
	/**
	 * @private
	 */
	,isInCache:function(value) {
		if(!value) {
			return false;
		}
		return !!this.selectCache[value];
	}
	,hasData:function() {
		var hasData = this.data 
			&& this.data[this.opt('serverRowsName')]
			&& this.data[this.opt('serverRowsName')].length > 0;
		return hasData;
	}
	/**
	 * 加载数据
	 * @param {Object} schData 查询参数,JSON数据
	 */
	,load:function(schData) {
		this.resetSelectCache();
		if(this.opt('url')){
			this.schData = schData || {};
			this.schData = $.extend(this.schData,this.opt('queryParams'));
			this.goPage(1);
		}else{
			var data = this.opt('data');
			this.loadData(data);
		}
		
	}
	/**
	 * 跳转到第几页
	 * @param {Number} pageIndex 跳转到第几页
	 */
	,goPage:function(pageIndex) {
		pageIndex = parseInt(pageIndex) || 1;
		this.page.goPage(pageIndex);
	}
	/**
	 * 重载行。等同于'load'方法，但是它将保持在当前页。
	 */
	,reload:function() {
		var schData = this.buildSchData();
		var ret = this.fire('BeforeLoad',{data:schData});
		
		if(ret === false) {
			return;
		}
		
		var url = this.opt('url');
		
		this.beforeReload();
		
		if(url) {
			var httpConfig = {
				url: url
				,method: this.opt('method')
				,data:schData
				,dataType:'json'
			}
			
			this.requestServer(httpConfig);
		}else{
			this.requestLocal(this.page.pageIndex,this.page.pageSize);
		}
	}
	,beforeReload:function() {
		this.view.reset();
	}
	/**
	 * @private
	 */
	,requestServer:function(config) {
		var that = this;
		$.ajax({
			type: config.method,
			url: config.url,
			traditional:true,
			dataType: config.dataType,
			data:config.data,
			success: function(data, textStatus, jqXHR){
	        	that.bindResult(data);
			},
			error:function(XMLHttpRequest, textStatus, errorThrown){
				that.fire('LoadError',{xhr:XMLHttpRequest, status:textStatus, error:errorThrown});
			}
		});
	}
	/**
	 * @private
	 */
	,requestLocal:function(pageIndex,pageSize) {
		var that = this;
		var newData = [];
		var rows = this.localData[this.opt('serverRowsName')];
		var firstIndex=1,total=0;
		
		if(that.opt('pagination') && rows.length > 0) {
			firstIndex = parseInt((pageIndex - 1) * pageSize);
			total = rows.length;
			newData = rows.slice(firstIndex,firstIndex+pageSize);
		}else{
			newData = rows;
		}
		var obj = {};
		
		obj[that.opt('serverRowsName')] = newData;
		obj[that.opt('serverPageIndexName')] = pageIndex;
		obj[that.opt('serverPageSizeName')] = pageSize;
		obj[that.opt('serverTotalName')] = total;
		
		that.bindResult(obj);
	}
	/**
	 * @private
	 */
	,reset:function() {
		this.view.reset();
	}
	/**
	 * 移除表格内容
	 */
	,removeData:function() {
		this.bindResult({});
	}
	/**
	 * 加载本地数据，旧的行将被移除。
	 * @param {Object} data 本地数据
	 */
	,loadData:function(data) {
		data = data || {};
		this.opt('url','');
		this.resetSelectCache();
		
		this.localData = this.formatData(data);
		
		this.goPage(1);
	}
	/**
	 * @private
	 */
	,bindResult:function(data) {
		this.fire('LoadSuccess',{data:data});
		
		data = this._processData(data);
		
		this.page.setPageInfo(data);
		
		this.data = data;
		
		this.setNextDo(function(){
			this.fire('RenderSuccess');
		})
	}
	/**
	 * 设置每页大小
	 * @param {Number} size 
	 */
	,setPageSize:function(size) {
		size = parseInt(size) || this.opt('pageSize');
		this.page.setPageSize(size);
	}
	/**
	 * 获取请求数据
	 * @return {JSON} 请求数据
	 */
	,getData:function() {
		return this.data;
	}
	/**
	 * 获取行数据
	 * @return {Array} 返回数组
	 */
	,getRows:function() {
		return this.data[this.opt('serverRowsName')];
	}
	/**
	 * 返回勾选的行数据
	 * @return {Array}
	 */
	,getChecked:function() {
		var checkedDatas = [];
		
		// 先添加缓存中的
		if(this.isSelectCache()) {
			var selectCache = this.getSelectCache();
			for(var idVal in selectCache) {
				if(selectCache[idVal]) {
					checkedDatas.push(selectCache[idVal]);
				}
			}
		}
		
		var checkedIndexs = this.view.getCheckedIndex();
		
		for(var i=0, len=checkedIndexs.length;i<len; i++) {
			var index = checkedIndexs[i];
			var row = this.getRowByIndex(index);
			var value = row[this.opt('idField')];
			
			var isNotInCache = !this.isInCache(value);
			if(isNotInCache) {
				checkedDatas.push(row);
			}
		}
		return checkedDatas;
	}
	/**
	 * 返回勾选的行数据的主键集合,getChecked()则是返回整个对象
	 * @return {Array} 如:[1,2,4]
	 */
	,getCheckIds:function() {
		var checkedRows = this.getChecked();
		var ret = [];
		var idField = this.opt('idField');
		
		for(var i=0, len=checkedRows.length;i<len; i++) {
			var row = checkedRows[i];
			ret.push(row[idField]);
		}
		
		return ret;
	}
	/**
	 * 返回第一个被选中的行或如果没有选中的行则返回null。
	 */
	,getSelected:function() {
		var checkedDatas = this.getChecked();
		if(checkedDatas.length == 0) {
			return null;
		}
		return checkedDatas[0];
	}
	/**
	 * 根据索引返回数据
	 */
	,getRowByIndex:function(index) {
		var rows = this.getRows();
		return rows[index];
	}
	/**
	 * 勾选全部
	 */
	,checkAll:function() {
		this.view.checkAll();
	}
	/**
	 * 不勾选全部
	 */
	,uncheckAll:function() {
		this.view.uncheckAll();
	}
	/**
	 * 不勾选全部
	 */
	,clearChecked:function() {
		this.uncheckAll();
	}
	/**
	 * 不勾选全部
	 */
	,unselectAll:function() {
		this.uncheckAll();
	}
	/**
	 * 不勾选全部
	 */
	,clearSelections:function() {
		this.uncheckAll();
	}
	/**
	 * 根据索引选择行
	 * @param {Number} index 行索引
	 */
	,selectRow:function(index) {
		this.view.selectRow(index);
	}
	/**
	 * 根据索引不选择行
	 * @param {Number} index 行索引
	 */
	,unselectRow:function(index) {
		this.view.unselectRow(index);
	}
	/**
	 * 根据索引勾选行
	 * @param {Number} index 行索引
	 */
	,checkRow:function(index) {
		this.view.checkRow(index);
	}
	/**
	 * 根据索不引勾选行
	 * @param {Number} index 行索引
	 */
	,uncheckRow:function(index) {
		this.view.uncheckRow(index);
	}
	/**
	 * 通过ID值参数选择一行。
	 */
	,selectRecord:function(idVal) {
		this.view.selectRecord(idVal);
	}
	/**
	 * @private
	 */
	,isCheckedAll:function() {
		return this.view.isCheckedAll();
	}
	/**
	 * 排序,只支持单属性排序
	 * @param {String} sortName 排序字段名
	 * @param {String} sortOrder 排序方式,即ASC,DESC
	 */
	,sort:function(sortName,sortOrder) {
		this.opt('sortName',sortName);
		this.opt('sortOrder',sortOrder);
		
		this.fire('SortColumn',{sortName:sortName,sortOrder:sortOrder});
		
		this.goPage(1);
	}
	/**
	 * @ignore
	 */
	,getViewClass:function() {
		return VUI.GridView;
	}
	/**
	 * @private
	 */
	,buildSchData:function() {
		var param = this.schData || {};
		var pageData = this.page.getPageData();
		
		param = $.extend(param,pageData);
		
		// 排序字段
		if(this.opt('sortName')) {
			param[this.opt('requestSortName')] = this.opt('sortName');
			param[this.opt('requestOrderName')] = this.opt('sortOrder');
		}
		
		return param;
	}
	,getTableWidth:function() {
		var width = this.opt('width');
		
		if(this.opt('autoFit')) {
			width = 'auto';
		}
		
		return width;
	}
	/**
	 * @private
	 */
	,formatData:function(data) {
		data = data || {};
		if($.isArray(data)) {
			var obj = {};
			obj[this.opt('serverRowsName')] = data;
			data = obj;
		}
		if(!data[this.opt('serverRowsName')]) {
			data[this.opt('serverRowsName')] = [];
		}
		return data;
	}
	/**
	 * @private
	 */
	,_processData:function(data) {
		data = this.formatData(data);
		var loadFilter = this.opt('loadFilter');
		if($.isFunction(loadFilter)) {
			data = loadFilter(data);
		}
		return data;
	}
	
},VUI.Component);


})();